import fetch from 'fermionjs/lib/fetch';
import errorCodesBuilder from '../../../helpers/errorCodesBuilder';
import authHeaderBuilder from './authHeaderBuilder';

const errorCodes = errorCodesBuilder('可用性监测任务执行失败');

export const taskIdsKey = 'CM:AVILIABLE:IDS';

const workerBuilder = type =>
	function worker(config, server) {
		const {
			app: { redis },
		} = server;
		const { createTaskApi, apiId, apiKey, username } = config;

		return async job => {
			const {
				target,
				taskType,
				sourceIp,
				collect,
				alert: { innerType, include, logic },
			} = job.data;

			let createTaskResp;
			try {
				const payload = [
					['username', username],
					['time', (Date.now() / 1000) | 0],
					[
						'data',
						JSON.stringify([
							{
								type,
								target: encodeURI(
									taskType === 'ping' ? new URL(target).hostname : target
								),
								server_ip: sourceIp || undefined,
								...collect,
								...(innerType === 'keyword'
									? {
											include,
											logic,
											inner_type: innerType,
									  }
									: {}),
							},
						]),
					],
				];
				const token = authHeaderBuilder(apiId, apiKey, payload);

				createTaskResp = await fetch(createTaskApi, {
					method: 'POST',
					headers: {
						AUTHORIZATION: token,
						'Content-Type': 'application/x-www-form-urlencoded',
					},
					body: new URLSearchParams(payload),
				});
				server.log.debug(
					{
						payload,
						api: createTaskApi,
						job: job.data,
						response: createTaskResp,
					},
					'[QUEUE][AVILIABLE]创建任务'
				);
				if (createTaskResp.code !== 0) {
					throw new Error(createTaskResp.msg);
				}
			} catch (err) {
				const error = errorCodes['[08]创建任务失败'].from(err);
				server.log.error(
					{ error, api: config.api, job: job.data },
					error.message
				);
				throw error;
			}

			const respData = createTaskResp?.data || [];
			try {
				await Promise.all(
					respData.map(({ tid, target }) => {
						return redis.hset(
							taskIdsKey,
							tid,
							JSON.stringify({
								...job.data,
								id: job.id,
								createTime: Date.now(),
							})
						);
					})
				);
			} catch (err) {
				const error = errorCodes['[08]保存可用性监测任务ID失败'].from(err);
				server.log.error(
					{ error, api: config.api, job: job.data },
					error.message
				);
				throw error;
			}
		};
	};

const http = workerBuilder('HTTP');
const ping = workerBuilder('PING');
export { http, ping };
